﻿using System;
using NTasking.Internals;

namespace NTasking
{

    /// <summary>
    /// Implement te Ada selective accept statement
    /// </summary>
    public class SelectiveAccept : SA.Base
    {

        #region Fields

        private Func<bool> _currentSimpleBarrier;


        private object _currentIndexedBarrier;

        #endregion


        #region Properties

        /// <summary>
        /// Gets or sets the current <see cref="IContinuable"/> last encoutered while building ths instance.
        /// </summary>
        /// <value>The current continuable.</value>
        internal IContinuable CurrentContinuable { get; set; }


        /// <summary>
        /// Gets or sets the simple barrier last encoutered while building ths instance.
        /// </summary>
        /// <value>The simple barrier.</value>
        internal Func<bool> CurrentSimpleBarrier
        {
            get
            {
                Func<bool> result = _currentSimpleBarrier;
                _currentSimpleBarrier = null;
                return result;
            }
            set { _currentSimpleBarrier = value; }
        }


        /// <summary>
        /// Gets or sets the else part.
        /// </summary>
        /// <value>The else.</value>
        internal Action Else { get; set; }


        /// <summary>
        /// Gets or sets a value indicating whether this instance has a terminate alternative.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance has terminate alternative; otherwise, <c>false</c>.
        /// </value>
        internal bool HasTerminate { get; set; }


        /// <summary>
        /// Gets or sets the number of open entries accept alternatives.
        /// </summary>
        /// <value>The open entries.</value>
        internal int OpenEntries { get; set; }


        /// <summary>
        /// Gets or sets the timeout corresponding to the closest open deay alterntive.
        /// </summary>
        /// <value>The timeout.</value>
        internal Timeout Timeout { get; set; }


        /// <summary>
        /// Gets or sets the task in which the select statement is located.
        /// </summary>
        /// <value>The task.</value>
        internal Task Task { get; private set; }

        #endregion


        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="SelectiveAccept"/> class.
        /// </summary>
        /// <param name="task">The task in which the select statement is located.</param>
        internal SelectiveAccept(Task task)
        {
            Select = this;
            Timeout = Timeout.Infinite;
            Task = task;
        }

        #endregion


        #region Methods

        /// <summary>
        /// Sets the indexed barrier last encoutered while building ths instance.
        /// </summary>
        /// <typeparam name="IndexT">The type of the barrier's index.</typeparam>
        /// <param name="barrier">The barrier.</param>
        internal void SetCurrentIndexedBarrier<IndexT>(Func<IndexT, bool> barrier)
        {
            _currentIndexedBarrier = barrier;
        }


        /// <summary>
        /// Gets the indexed barrier last encoutered while building ths instance.
        /// </summary>
        /// <typeparam name="IndexT">The type of the barrier's index.</typeparam>
        /// <returns>The barrier</returns>
        internal Func<IndexT, bool> GetCurrentIndexedBarrier<IndexT>()
        {
            Func<IndexT, bool> result = _currentIndexedBarrier as Func<IndexT, bool>;
            _currentIndexedBarrier = null;
            return result;
        }

        #endregion

    }

}